package com.next

import grails.converters.JSON
import grails.gorm.transactions.Transactional
import grails.validation.ValidationException
import net.sf.jasperreports.engine.JasperCompileManager
import net.sf.jasperreports.engine.JasperRunManager
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
import nine.reports.ReportFormat
import org.springframework.security.access.annotation.Secured

import static org.springframework.http.HttpStatus.*

@Secured(['ROLE_ADMINISTRATOR'])
@Transactional(readOnly = true)
class JasperFileController {

    JasperFileService jasperFileService
    FileServerService fileServerService
    ComponentService componentService

    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    @Secured(['ROLE_ADMINISTRATOR'])
    @Transactional
    def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond jasperFileService.list(params), model:[jasperFileCount: jasperFileService.count()]
    }

    @Secured(['ROLE_ADMINISTRATOR'])
    @Transactional
    def show(Long id) {
        respond jasperFileService.get(id)
    }

    @Secured(['ROLE_ADMINISTRATOR'])
    @Transactional
    def create() {
        respond new JasperFile(params)
    }

    @Secured(['ROLE_ADMINISTRATOR'])
    @Transactional
    def save(JasperFile jasperFile) {
        if (jasperFile == null) {
            notFound()
            return
        }

        try {
            jasperFileService.save(jasperFile)
        } catch (ValidationException e) {
            respond jasperFile.errors, view:'create'
            return
        }

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [message(code: 'jasperFile.label', default: 'JasperFile'), jasperFile.id])
                redirect jasperFile
            }
            '*' { respond jasperFile, [status: CREATED] }
        }
    }

    @Secured(['ROLE_ADMINISTRATOR'])
    @Transactional
    def edit(Long id) {
        respond jasperFileService.get(id)
    }

    @Secured(['ROLE_ADMINISTRATOR'])
    @Transactional
    def update(JasperFile jasperFile) {
        if (jasperFile == null) {
            notFound()
            return
        }

        try {
            jasperFileService.save(jasperFile)
        } catch (ValidationException e) {
            respond jasperFile.errors, view:'edit'
            return
        }

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'jasperFile.label', default: 'JasperFile'), jasperFile.id])
                redirect jasperFile
            }
            '*'{ respond jasperFile, [status: OK] }
        }
    }

    @Secured(['ROLE_ADMINISTRATOR'])
    @Transactional
    def delete(Long id) {
        if (id == null) {
            notFound()
            return
        }

        jasperFileService.delete(id)

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'jasperFile.label', default: 'JasperFile'), id])
                redirect action:"index", method:"GET"
            }
            '*'{ render status: NO_CONTENT }
        }
    }

    protected void notFound() {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'jasperFile.label', default: 'JasperFile'), params.id])
                redirect action: "index", method: "GET"
            }
            '*'{ render status: NOT_FOUND }
        }
    }

    @Secured(['permitAll'])
    def getUploadToken()
    {
        def token = fileServerService.getUploadToken("jasperFile/callbackByQiniu")
        render([status: "success", token: token] as JSON)
        return
    }

    @Secured(['permitAll'])
    @Transactional
    def callbackByQiniu()
    {
        println "*********************** callbackByQiniu  ****************************"
        def json = request.JSON
        println "json:" + json
        String fileName = json["fileName"]
        def files = []
        def sfile = [:]
        def o = [:]
        sfile['thumbnailUrl'] = "http://p66wk755l.bkt.clouddn.com/" + fileName
        sfile['name'] = "下载模板"
        files.add(sfile)
        o['files'] = files
        render o as JSON
        return
    }

    @Secured(['ROLE_ADMINISTRATOR'])
    def downloadJasperReport(){
        def jasperFile = JasperFile.findById(params.id)
        def map = componentService.evaluate(jasperFile.component,jasperFile)
        def beanColDataSource = new JRBeanCollectionDataSource(map.data)
        def parameters = [:]
        def filebyte
        if (params.format == "PDF"){
            filebyte = JasperRunManager.runReportToPdf(JasperCompileManager.compileReport(new URL(jasperFile.fileUrl).openConnection().getInputStream()),parameters,beanColDataSource)
            OutputStream out
            try
            {
                out = response.getOutputStream()
                out.write(filebyte,0,filebyte.length)
                out.flush()
                out.close()
            }
            catch (Exception e)
            {
                e.printStackTrace()
            }
            return
        }else if (params.format == "HTML"){
            def fileName = jasperFile.fileUrl.substring(jasperFile.fileUrl.lastIndexOf("/")+1)
            def webRootDir = servletContext.getRealPath("/")
            def jasperfile = webRootDir+"jasper/"+fileName
            File file = new File(webRootDir, "jasper/"+fileName)
            if (!file.exists()){
                try {
                    // 构造URL
                    URL url = new URL(jasperFile.fileUrl)
                    // 打开连接
                    URLConnection con = url.openConnection()
                    //设置请求超时为5s
                    con.setConnectTimeout(25*1000)
                    // 输入流
                    InputStream is = con.getInputStream()
                    // 1K的数据缓冲
                    byte[] bs = new byte[1024]
                    // 读取到的数据长度
                    int len
                    // 输出的文件流
                    def file1 = new File(jasperfile)
                    OutputStream os = new FileOutputStream(file1)
                    // 开始读取
                    while ((len = is.read(bs)) != -1) {
                        os.write(bs, 0, len)
                    }
                    // 完毕，关闭所有链接
                    os.close()
                    is.close()
                    println(jasperfile+"模板文件下载完成！")
                } catch (IOException e) {
                    e.printStackTrace()
                }
            }
            filebyte = JasperRunManager.runReportToHtmlFile(JasperCompileManager.compileReportToFile(jasperfile),parameters,beanColDataSource)
            OutputStream out
            try
            {
                out = response.getOutputStream()
                def inputStream = new FileInputStream(filebyte)
                byte[] buffer = new byte[1024]
                int i = -1
                while ((i = inputStream.read(buffer)) != -1) {
                    out.write(buffer, 0, i)
                }
                out.flush()
                out.close()
                inputStream.close()
            }
            catch (Exception e)
            {
                e.printStackTrace()
            }
            return
        }
        return
    }
}
